Appearance
[中文版本](/posts/c教程/zh-CN/02-语言基础/018-Return Values and Function Signatures)
Functions not only perform tasks but often communicate results back to the caller. They do this through return values. Every C function has a signature, a declaration that defines its return type, name, and parameters. Getting comfortable with signatures and return values helps you write clean, predictable, and modular programs.
Function Signatures Explained
A function signature looks like this:
return_type function_name(parameter_list);It tells the compiler:
- What kind of value the function returns (
int,double,void, etc.) - What the function is called
- What arguments it expects and their types
Example:
int max(int a, int b);This says: “max is a function that takes two integers and returns an integer.”
Returning Values
You use thereturn keyword to send a value back from a function.
int add(int x, int y) {
return x + y;
}The type of the value you return must match the function’s declared return type.
If a function doesn’t need to return anything, declare it asvoid:
void greet(void) {
printf("Hello!\n");
}Avoid function can still perform actions, it just doesn’t produce a result.
Multiple Return Points
You can return early if certain conditions are met.
int divide(int a, int b) {
if (b == 0) {
printf("Error: division by zero!\n");
return 0;
}
return a / b;
}This is common for error handling or input validation.
Returning Different Data Types
You can return any type, not just integers.
double average(double a, double b) {
return (a + b) / 2.0;
}
char first_letter(const char *word) {
return word[0];
}
_Bool is_even(int n) {
return n % 2 == 0;
}For more complex data, you’ll later learn how to return pointers or structs.
Tiny Code
Here’s a complete example showing several return types and signatures:
#include <stdio.h>
#include <stdbool.h>
// function declarations
int add(int x, int y);
double divide(double a, double b);
bool is_even(int n);
void greet(const char *name);
int main(void) {
greet("C Programmer");
int sum = add(7, 3);
double quotient = divide(10.0, 4.0);
bool check = is_even(sum);
printf("Sum: %d\n", sum);
printf("Quotient: %.2f\n", quotient);
printf("Is sum even? %s\n", check ? "Yes" : "No");
return 0;
}
// function definitions
int add(int x, int y) {
return x + y;
}
double divide(double a, double b) {
if (b == 0.0) {
printf("Cannot divide by zero.\n");
return 0.0;
}
return a / b;
}
bool is_even(int n) {
return n % 2 == 0;
}
void greet(const char *name) {
printf("Hello, %s!\n", name);
}Compile and run:
gcc return_demo.c -o return_demo
./return_demoOutput:
Hello, C Programmer!
Sum: 10
Quotient: 2.50
Is sum even? YesWhy It Matters
Return values are how functions communicate. By designing clear and meaningful signatures:
- You make your code predictable, every function has a defined purpose and output.
- The compiler can check correctness, mismatched types raise warnings.
- You can compose functions, one function’s return becomes another’s input.
In large systems, consistent signatures and meaningful return types form the backbone of good API design.
Try It Yourself
- Write a function
max(a, b)that returns the larger of two integers. - Write a function
to_upper(char c)that returns an uppercase version of a character. - Modify a
divide()function to return-1if division by zero occurs. - Create a
sum_to_n(int n)that returns the sum of all numbers from 1 ton. - Try using a
voidfunction that prints the result of another function call.
Return values give your functions purpose, they turn simple actions into reusable building blocks that make your programs expressive, modular, and alive.
